#include <iostream>
#include <cassert>
#include <cstring>
#include <unistd.h>
#include <signal.h>

using namespace std;
       
static void PrintPending(const sigset_t &pending)
{
    cout << "当前进程的pending位图: ";
    for(int signo = 1; signo <= 31; signo++)
    {
        if(sigismember(&pending, signo)) cout << "1";
        else cout << "0";
    }
    cout << "\n";
}

static void handler(int signo)
{
    cout << "对特定信号："<< signo << "执行捕捉动作" << endl;
    int cnt = 30;
    while(cnt)
    {
        cnt--;

        sigset_t pending;
        sigemptyset(&pending); // 不是必须的
        sigpending(&pending);
        PrintPending(pending);
        sleep(1);
    }
}

int main()
{

    // 2.0 设置对2号信号的的自定义捕捉
    signal(2, handler);
    int cnt = 0;
    //1. 屏蔽2号信号
    sigset_t set, oset;
    // 1.1 初始化
    sigemptyset(&set);
    sigemptyset(&oset);
    // 1.2 将2号信号添加到set中
    sigaddset(&set, SIGINT/*2*/);
    // sigaddset(&set, 3/*2*/);
    // sigaddset(&set, 9/*2*/);
    // 1.3 将新的信号屏蔽字设置进程
    sigprocmask(SIG_BLOCK, &set, &oset);

    //2. while获取进程的pending信号集合，并01打印

    while(true)
    {
        // 2.1 先获取pending信号集
        sigset_t pending;
        sigemptyset(&pending); // 不是必须的
        int n = sigpending(&pending);
        assert(n == 0);
        (void)n; //保证不会出现编译是的warning

        // 2.2 打印，方便我们查看
        PrintPending(pending);

        // 2.3 休眠一下
        sleep(1);

        // 2.4 10s之后，恢复对所有信号的block动作
        if(cnt++ == 10)
        {
            cout << "解除对2号信号的屏蔽" << endl; //先打印
            sigprocmask(SIG_SETMASK, &oset, nullptr); //?
        }
    }


}